﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TiposComuns.Objectos;
using System.Runtime.CompilerServices;

namespace Servidor.Objectos
{
    /// <summary>
    /// Logs all the actions done by this server, in order to preserve consistency of the replicated data
    /// </summary>
    [Serializable]
    public class Logfile
    {
        #region Attributes
        private SerializableDictionary<IDMsg, Action> actions =
            new SerializableDictionary<IDMsg, Action>();       //Actions performed by the server
        #endregion

        #region Modifiers
        public SerializableDictionary<IDMsg, Action> Actions
        {
            get { return actions; }
            set { actions = value; }
        }
        #endregion

        #region Methods

        /// <summary>
        /// Register a new action
        /// </summary>
        /// <param name="action">New action</param>
        [MethodImpl(MethodImplOptions.Synchronized)]
        public void Register(Action action)
        {
            this.actions.Add(action.Id,action);
        }

        /// <summary>
        /// Synchronizes the internal state of the user
        /// </summary>
        /// <param name="user">Internal state of the user</param>
        /// <param name="list">List of new actions</param>
        public void Synchronize(User user, List<Action> list)
        {
            foreach (Action ac in list)
            {
                actions.Add(ac.Id, ac);
                ac.Execute(user);
            }
        }



        public List<Action> GetActionsSince(IDMsg lastid)
        {
            List<Action> res = new List<Action>();

            IEnumerable<IDMsg> data = (from db in actions.Keys  where (db.ID >= lastid.ID)
                                                                select db);
            foreach (IDMsg id in data)
            {
                res.Add(actions[id]);
            }

            return res;
        }

        /// <summary>
        /// Executes an action an updates the internal state of the user
        /// </summary>
        /// <param name="user">Internal state of the user</param>
        /// <param name="id">Identifier of the action</param>
        public void Execute(User user, IDMsg id)
        {
            actions[id].Execute(user);
        }

        public IDMsg GetLastClient()
        {
            IDMsg max = null;
            
            foreach(Action a in this.actions.Values)
            {
                max = (max == null || (a.Id.isClient && max.ID < a.Id.ID)) ? a.Id : max;
            }

            return max;
        }
        #endregion
    }
}
